package com.wxzhou.wangzhuan.event;

import com.wxzhou.wangzhuan.dto.UserInfoDto;
import com.wxzhou.wangzhuan.entity.AdLog;
import com.wxzhou.wangzhuan.entity.AdsenseAndChannel;
import com.wxzhou.wangzhuan.repository.AdRespository;
import com.wxzhou.wangzhuan.service.AdRateLimitService;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.event.ObservesAsync;
import jakarta.inject.Inject;
import org.jboss.logging.Logger;

import java.util.List;

/**
 * 广告拉取成功事件服务
 */
@ApplicationScoped
public class AdEventService {

    private static final Logger LOG = Logger.getLogger(AdEventService.class);

    @Inject
    AdRespository adRespository;

    @Inject
    AdRateLimitService adRateLimitService;

    /**
     * 拉取成功,通过校验后,直接将数据进行入库.
     *
     * @param event
     */
    public void processProLogEvents(@ObservesAsync PreAdLogEvent event) {
        LOG.debugf("插入预拉数据到数据库");

        AdsenseAndChannel aac = event.getAdsenseAndChannel();

        UserInfoDto userInfo = event.getUserInfo();

        AdLog adLog = AdLog.buildPreAd(aac.getAdid(), event.getAdIdSn(), userInfo.getUserId(), userInfo.getDeviceId(), aac.getAd_channel(), aac.getAd_nt(), aac.getSense())
                .adType(aac.getAd_type())
                .appChannel(aac.getApp_channel())
                .remark(event.getRemark())
                .build();

        adRespository.insertPreLog(adLog)
                .subscribe()
                .with(
                        success -> {
                            LOG.debug("预拉取数据执行成功");
                        },
                        failure -> LOG.error("记录日志失败", failure)
                );
    }

    /**
     * 日志事件
     *
     * @param event
     */
    public void processAdLogEvents(@ObservesAsync AdLogEvent event) {
        List<AdLog> adLogs = event.getAdLogs();
        if (!adLogs.isEmpty()) {
            adRespository.batchInsert(adLogs).subscribe().with(integer -> {
                LOG.infof("插入成功，影响行数：" + integer);
            }, throwable -> {
                LOG.errorf(throwable, "批量执行插入广告数据发生异常");
            });
        }
    }

    /**
     * 获取到日志请求数据事件,执行写入到redis,便于后续做请求次数拦截!
     *
     * @param event
     */
    public void processAdRequestEvents(@ObservesAsync AdReportLogEvent event) {
        if (event != null) {
            adRateLimitService.batchRecordAdRequest(event.getAdLogs(), event.getApp_channel(), event.getDeviceId(), event.getUserid())
                    .subscribe().with(integer -> {
                        LOG.infof("记录请求日志到redis成功");
                    }, throwable -> {
                        LOG.errorf(throwable, "记录请求日志到redis失败");
                    });
        }
    }
}
